using AutoMapper;
using BackData;
using Domain;
using Domain.工艺工序;
using Infratructure;
using MediatR;
using Microsoft.Extensions.Logging;
using System.Transactions;
using Team.API.Applocation.Command.Makesteps;
using Yitter.IdGenerator;

namespace Team.API.Applocation.Hanldler.Makesteps
{
    /// <summary>
    /// 保存工艺工序子工序列表处理器
    /// 清除旧的子工序（根据父级工序ID），保存新的子工序列表
    /// </summary>
    public class SaveMakestepChildrenHandler : IRequestHandler<SaveMakestepChildrenCommand, APIResult<bool>>
    {
        private readonly IRepository<Makestepmodel> repository;
        private readonly IRepository<Nlogmodel> logRepository;
        private readonly IMapper mapper;
        private readonly ILogger<SaveMakestepChildrenHandler> logger;

        public SaveMakestepChildrenHandler(
            IRepository<Makestepmodel> repository,
            IRepository<Nlogmodel> logRepository,
            IMapper mapper,
            ILogger<SaveMakestepChildrenHandler> logger)
        {
            this.repository = repository;
            this.logRepository = logRepository;
            this.mapper = mapper;
            this.logger = logger;
        }

        /// <summary>
        /// 保存工艺工序子工序列表
        /// 1. 软删除旧的子工序（根据父级工序ID）
        /// 2. 创建新的子工序记录
        /// 3. 记录操作日志
        /// </summary>
        /// <param name="request">保存命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>保存结果</returns>
        public async Task<APIResult<bool>> Handle(SaveMakestepChildrenCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 验证必填参数
                if (request.ParentId <= 0)
                {
                    return APIResult<bool>.Faile("父级工序ID不能为空");
                }

                if (request.Children == null || request.Children.Count == 0)
                {
                    return APIResult<bool>.Faile("子工序列表不能为空");
                }

                // 获取当前操作人
                var currentUser = request.CurrentUserName ?? "系统";

                // 获取父级工序信息（用于日志记录）
                var parentEntity = await repository.GetByIdAsync(request.ParentId);
                if (parentEntity == null || parentEntity.IsDel)
                {
                    return APIResult<bool>.Faile("父级工序不存在或已删除");
                }

                // 使用事务确保数据一致性
                using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    try
                    {
                        // 1. 软删除旧的子工序（根据父级工序ID）
                        var oldChildren = await repository.GetAll()
                            .Where(x => !x.IsDel && x.Parentid == request.ParentId)
                            .ToListAsync();

                        if (oldChildren != null && oldChildren.Count > 0)
                        {
                            // 同时删除所有子节点的子节点（递归删除）
                            var oldIds = oldChildren.Select(x => x.Id).ToList();

                            // 递归查找所有子节点并删除
                            var allOldIds = new List<long>(oldIds);
                            foreach (var id in oldIds)
                            {
                                var grandchildren = await GetChildrenIdsAsync(id);
                                allOldIds.AddRange(grandchildren);
                            }

                            // 软删除所有节点
                            foreach (var id in allOldIds.Distinct())
                            {
                                var entity = await repository.GetByIdAsync(id);
                                if (entity != null)
                                {
                                    entity.IsDel = true;
                                    await repository.UpdateAsync(entity);
                                }
                            }

                            logger.LogInformation("[工艺工序-保存子工序] 已删除旧的子工序，父级工序ID={ParentId}，共{Count}条",
                                request.ParentId, allOldIds.Count);
                        }

                        // 2. 创建新的子工序记录（按排序顺序）
                        var sortedChildren = request.Children.OrderBy(x => x.SortOrder).ToList();
                        var newIds = new List<long>();

                        foreach (var childDto in sortedChildren)
                        {
                            var entity = new Makestepmodel
                            {
                                Id = YitIdHelper.NextId(),
                                Processname = childDto.Processname,
                                Processcode = childDto.Processcode,
                                Processdescription = childDto.Processdescription ?? "",
                                Version = childDto.Version ?? parentEntity.Version,
                                Goodsname = childDto.Goodsname ?? parentEntity.Goodsname,
                                Deliverables = childDto.Deliverables ?? "",
                                Kahuna = childDto.Kahuna ?? "",
                                Departmentname = childDto.Departmentname ?? "",
                                IsUse = childDto.IsUse,
                                SpanTime = childDto.SpanTime,
                                EquipmentId = childDto.EquipmentId,
                                Parentid = request.ParentId, // 设置父级ID
                                IsDel = false
                            };

                            // 将备注信息保存到描述字段（如果描述为空）
                            if (string.IsNullOrWhiteSpace(entity.Processdescription) && !string.IsNullOrWhiteSpace(childDto.Remark))
                            {
                                entity.Processdescription = childDto.Remark;
                            }

                            var effect = await repository.AddAsync(entity);
                            if (effect <= 0)
                            {
                                throw new Exception($"保存子工序失败：{entity.Processname}");
                            }
                            newIds.Add(entity.Id);
                        }

                        // 3. 记录操作日志
                        try
                        {
                            var logEntity = new Nlogmodel
                            {
                                Id = YitIdHelper.NextId(),
                                Operatingtime = DateTime.Now,
                                Operator = currentUser,
                                Message = $"{currentUser}保存工艺工序子工序：{parentEntity.Processname}（{parentEntity.Processcode}），共{newIds.Count}条子工序",
                                Category = "Process",
                                Otherkey = request.ParentId,
                                IsDel = false
                            };
                            var logEffect = await logRepository.AddAsync(logEntity);
                            if (logEffect <= 0)
                            {
                                logger.LogWarning("[工艺工序-保存子工序] 日志写入失败，操作人：{User}，父级工序ID：{ParentId}",
                                    currentUser, request.ParentId);
                            }
                        }
                        catch (Exception logEx)
                        {
                            logger.LogWarning(logEx, "[工艺工序-保存子工序] 日志写入异常，操作人：{User}，父级工序ID：{ParentId}",
                                currentUser, request.ParentId);
                        }

                        // 提交事务
                        transaction.Complete();

                        logger.LogInformation("[工艺工序-保存子工序] 保存成功，操作人：{User}，父级工序ID={ParentId}，共{Count}条",
                            currentUser, request.ParentId, newIds.Count);

                        return APIResult<bool>.Ok("子工序保存成功", true);
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, "[工艺工序-保存子工序] 保存失败，操作人：{User}，父级工序ID：{ParentId}",
                            currentUser, request.ParentId);
                        return APIResult<bool>.Faile($"子工序保存失败：{ex.Message}");
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "[工艺工序-保存子工序] 执行异常，父级工序ID：{ParentId}",
                    request.ParentId);
                return APIResult<bool>.Faile($"子工序保存失败：{ex.Message}");
            }
        }

        /// <summary>
        /// 递归获取所有子节点的ID
        /// </summary>
        /// <param name="parentId">父级ID</param>
        /// <returns>子节点ID列表</returns>
        private async Task<List<long>> GetChildrenIdsAsync(long parentId)
        {
            var children = await repository.GetAll()
                .Where(x => !x.IsDel && x.Parentid == parentId)
                .ToListAsync();

            var result = new List<long>();
            if (children != null && children.Count > 0)
            {
                result.AddRange(children.Select(x => x.Id));
                foreach (var child in children)
                {
                    var grandchildren = await GetChildrenIdsAsync(child.Id);
                    result.AddRange(grandchildren);
                }
            }

            return result;
        }
    }
}

